package com.tron.service.handler;
/**
 *   绑定的处理器处理事件
 *   自定义Handle需要继承netty规定好的某个HandlerAdapter
 */


import com.tron.context.QuartzContext;
import com.tron.context.RedisContext;
import com.tron.entity.PayOrder;
import com.tron.utils.tron.TronUtils;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

@Data
@Slf4j
public class NettyServerHandler extends ChannelInboundHandlerAdapter {

    //注入任务调度
    private Map<String,Object> data =  new HashMap<>();

    // 存储定时任务的引用，以便之后取消任务
    private ScheduledFuture<?> scheduledFuture;

    TronUtils tronUtils;
    RedisContext redisContext;
    RedisTemplate redisTemplate;

    public NettyServerHandler(TronUtils tronUtils, RedisContext redisContext, RedisTemplate redisTemplate) {
        this.tronUtils = tronUtils;
        this.redisContext=redisContext;
        this.redisTemplate=redisTemplate;
    }



    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        super.channelRegistered(ctx);
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        super.channelUnregistered(ctx);
    }

    /**
     * 当客户端连接到服务器完成就会出发该方法
     * @param ctx
     * @throws Exception 抛出异常
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx){
        log.info("客户端连接通过建立完成:{}",ctx.toString());
    }

    /**
     * 读取客户端发送的数据
     * @param ctx 上下文对象,含通道channel,管代pipeline
     * @param msg 客户端发送的消息
     * @throws Exception 抛出异常
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        ByteBuf buf =(ByteBuf) msg;
        System.out.println("接收到客户端消息："+buf.toString(CharsetUtil.UTF_8));
        this.data.put("key",buf.toString(CharsetUtil.UTF_8));
    }

    /**
     * 数据读取完毕处理方法
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {
        String key = (String) this.data.get("key");
        System.out.println(tronUtils);
        //开启一个线程
        Runnable runnable = () -> {
            PayOrder payOrder = null;
            //取数据
            String payKey = redisContext.getOrderPayKey(key);
            Object o = redisTemplate.opsForValue().get(payKey);
            if(Objects.isNull(o)){
                String str = "订单失败!----->>@!";
                ByteBuf buf = Unpooled.copiedBuffer(str.getBytes(CharsetUtil.UTF_8));
                ctx.writeAndFlush(buf);
                ctx.close(); //如果没有数据 或者是已过期 则自动断开
                stopTask(); //关闭线程
                return;
            }

            //有数据处理业务
            try {
                payOrder = (PayOrder) o;
                if(Objects.nonNull(payOrder.getAddress())){
                    Long aLong = tronUtils.searchTrcBalance(payOrder.getAddress(), payOrder.getPrivateKey());
                    log.info("比较金额---->>"+aLong+"||"+ payOrder.getAmount());
                    //1TRX = 1000000
                    if(aLong >= payOrder.getAmount() * 1000000){
                        //返回数据
                        String str = "完成订单!----->>" + payOrder.getAmount();
                        ByteBuf buf = Unpooled.copiedBuffer(str.getBytes(CharsetUtil.UTF_8));
                        String accountReuseKey = redisContext.getAccountReuse(payOrder.getAddress());
                        Boolean delete = redisTemplate.delete(accountReuseKey);//移除key
                        ctx.writeAndFlush(buf);
                        ctx.close(); //关闭连接
                        stopTask(); //关闭线程
                        return;
                    }else{
                        String str = "等待支付----->>当前余额:" +aLong;
                        ByteBuf buf = Unpooled.copiedBuffer(str.getBytes(CharsetUtil.UTF_8));
                        ctx.writeAndFlush(buf);
                    }
                }
            } catch (Exception e){
                log.error("Order对象转换失败！！");
                stopTask();
            }
        };

        // 安排一个定时任务
        scheduledFuture = ctx.channel().eventLoop().scheduleAtFixedRate(runnable, 0, 10, TimeUnit.SECONDS);
        //createTask(key);
//        int totalRuns = 10;
//        AtomicInteger currentRun = new AtomicInteger(0);
//        ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
//        Runnable task = () -> {
//            String str = "客户端Netty返回--->"+key;
//            ByteBuf buf = Unpooled.copiedBuffer(str.getBytes(CharsetUtil.UTF_8));
//            ctx.writeAndFlush(buf);
//            int runCount = currentRun.incrementAndGet();
//            if (runCount >= totalRuns) {
//                executorService.shutdown();
//                //ctx.close();
//            }
//        };
//
//        // 每500毫秒执行一次任务
//        executorService.scheduleAtFixedRate(task, 0, 500, TimeUnit.MILLISECONDS);
        //ctx.close();
       // super.channelReadComplete(ctx);
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);
    }

    @Override
    public void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception {;
        super.channelWritabilityChanged(ctx);
    }

    /**
     * 如果发生异常 或者是用户主动断开连接 会被触发
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
        //不关闭这个线程 原因是有可能用户不小心关闭了连接 但是支付成功了 我们需要监听支付成功
        //  stopTask(); //关闭线程
        System.out.println("有异常发生么..........");
        //super.exceptionCaught(ctx, cause);
    }

    public String createTask(String key){
        try {
            //QuartzBean
            QuartzContext quartzContext = new QuartzContext();
            quartzContext.setJobName("job_"+key);
            quartzContext.setCronExpression("*/10 * * * * ?");
            quartzContext.setJobClass("com.tron.task.tron.OrderListener");

            Map<String,Object> map = new HashMap<>();
            map.put("key",key);
            quartzContext.setData(map);
            //QuartzUtils.createScheduleJob(scheduler, quartzContext);
        } catch (Exception e) {
            return "创建失败";
        }
        return "创建成功";
    }

    public void stopTask() {
        // 如果scheduledFuture不为null且未被取消，则取消任务
        if (scheduledFuture != null && !scheduledFuture.isCancelled()) {
            scheduledFuture.cancel(false);
            scheduledFuture = null; // 将引用置为null，避免内存泄漏
        }
    }

}
